package 反射1;

import java.lang.reflect.Field;

/**
 * 编译时，会在堆中创建一个class对象
 * 反射初体验，简单api调用体验，创建反射类对象的四种方法，创建类实例
 */
public class TestCarReflection {
    public static void main(String[] args) throws Exception {
//        通过 Class.forName 获取到的 aClass 是 Car 类的 Class 对象（获取反射类对象--方式1）
        String classReference="反射1.Car";
        Class<?> aClass = Class.forName(classReference);
        System.out.println("aClass = " + aClass);
//        getClass()返回对象运行时的 Class 对象
        System.out.println("aClass.getClass() = " + aClass.getClass());
        System.out.println("aClass.getPackage().getName() = " + aClass.getPackage().getName());
//        getName()获取类的全限定名（包含包名和类名）
        System.out.println("aClass.getName() = " + aClass.getName());
//        ！！！要强转成car,创建该类的一个新实例,相当于new一个对象
        /**
         * Car car = (Car) aClass.newInstance();---1
         * Object o = aClass.newInstance();---2
         * 其实无需强转，只是不强转的话Object类的o不能访问car类的特有属性和方法，要解决这个问题
         *1.要么继续强转
         *2.要么使用反射调用，在反射2.TestBoss中说明如何调用
         */

        Object o = aClass.newInstance();
        System.out.println("car = " + o);
//        通过反射获取属性，getField()用于获取类中指定名称的公共字段（属性）
        Field field = aClass.getField("brand");
        System.out.println("field = " + field);
//        获取类中所有的公共字段（属性），并返回一个fields数组
        Field[] fields = aClass.getFields();
        for(Field f : fields){
            System.out.println("f.getName() = " + f.getName());
        }

        System.out.println("-------获取反射类对象--------");
//        方式2：硬编译
        Car car1 = new Car();
        Class<? extends Car> aClass1 = car1.getClass();
        System.out.println("aClass1 = " + aClass1);
//        方式3：通过Class属性获取
        System.out.println("Car.class = " + Car.class);
//        方式4：通过类加载器
        ClassLoader classLoader = o.getClass().getClassLoader();
        Class<?> aClass2 = classLoader.loadClass(classReference);
        System.out.println("aClass2 = " + aClass2);

        System.out.println("--------用hashcode值测试是否是同一个对象--------");
        System.out.println("aClass.hashCode() = " + aClass.hashCode());
        System.out.println("aClass1 = " + aClass1);
        System.out.println("Car.class = " + Car.class);
        System.out.println("aClass2 = " + aClass2);

        System.out.println("--------也可以反射基本类型-------");
        System.out.println("int.class = " + int.class);
    }
}
